package gdut.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;

import gdut.BlogServiceAPI;
import gdut.common.pojo.dataobject.UserInfo;
import gdut.exception.BlogException;
import gdut.mapper.UserInfoMapper;
import gdut.pojo.BlogInfoResponse;
import gdut.pojo.Result;
import gdut.service.UserService;
import gdut.utils.*;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import pojo.UserInfoRegisterRequest;
import pojo.UserInfoRequest;
import pojo.UserInfoResponse;
import pojo.UserLoginResponse;

import java.util.HashMap;
import java.util.Map;
@Slf4j
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserInfoMapper userInfoMapper;

    @Resource
    private BlogServiceAPI blogServiceAPI;

    @Resource
    private RedisUtils redisUtils;

    private static final long EXPIRE_TIME = 14 * 24 * 60 * 60;
    private static final String PREFIX="user";

    @Override
    public UserLoginResponse login(UserInfoRequest user) {
        //验证账号密码是否正确
        UserInfo userInfo = queryUserInfo(user.getUserName());
        if (userInfo==null || userInfo.getId()==null){
            throw new BlogException("用户不存在");
        }
        if (!SecurityUtil.verify(user.getPassword(),userInfo.getPassword())){
            throw new BlogException("用户密码不正确");
        }
        //账号密码正确的逻辑
        Map<String,Object> claims = new HashMap<>();
        claims.put("id", userInfo.getId());
        claims.put("name", userInfo.getUserName());

        String jwt = JWTUtils.genJwt(claims);
        return new UserLoginResponse(userInfo.getId(), jwt);
    }

    public UserInfo queryUserInfo(String userName){
        if(userName==null){
            return null;
        }
        //先从Redis中找
        String key=buildKey(userName);
        boolean exists=redisUtils.checkKey(key);
        if(exists){
            //说明Redis中存在
            //存进Redis中的用户信息是JSON
            String json=redisUtils.get(key);
            log.info("queryUserInfo 从Redis中获取数据");
            UserInfo userInfo=JsonUtils.parseJson(json,UserInfo.class);
            //如果查找失败了，转去数据库查询
            return userInfo==null?selectUserInfoByName(userName):userInfo;
        }else{
            //Redis中不存在，从数据库中获取
            log.info("queryUserInfo 从数据库中获取数据");
            UserInfo userInfo=selectUserInfoByName(userName);
            //将数据存入Redis中
            redisUtils.set(key,JsonUtils.toJson(userInfo),EXPIRE_TIME);
            return userInfo;
        }
    }

    @Override
    public UserInfoResponse getUserInfo(Integer userId) {
        UserInfoResponse userInfoResponse = new UserInfoResponse();
        UserInfo userInfo = selectUserInfoById(userId);
        BeanUtils.copyProperties(userInfo, userInfoResponse);
        return userInfoResponse;
    }

    @Override
    public UserInfoResponse selectAuthorInfoByBlogId(Integer blogId) {
        UserInfoResponse userInfoResponse = new UserInfoResponse();
        //1. 根据博客ID, 获取作者ID
        Result<BlogInfoResponse> blogDetail = blogServiceAPI.getBlogDetail(blogId);
        //2. 根据作者ID, 获取作者信息
        if (blogDetail == null || blogDetail.getData() == null){
            throw new BlogException("博客不存在");
        }
        UserInfo userInfo = selectUserInfoById(blogDetail.getData().getUserId());
        BeanUtils.copyProperties(userInfo, userInfoResponse);
        return userInfoResponse;
    }

    @Override
    public Integer register(UserInfoRegisterRequest userInfoRegisterRequest) {
        //校验参数
        checkUserInfo(userInfoRegisterRequest);
        //用户注册
        UserInfo userInfo=new UserInfo();
        userInfo.setUserName(userInfoRegisterRequest.getUserName());
        userInfo.setPassword(SecurityUtil.encrypt(userInfoRegisterRequest.getPassword()));
        userInfo.setGithubUrl(userInfoRegisterRequest.getGiteeUrl());
        userInfo.setEmail(userInfoRegisterRequest.getEmail());
        try{
            int result=userInfoMapper.insert(userInfo);
            if(result==1){
                //插入Redis中
                redisUtils.set(buildKey(userInfo.getUserName()), JsonUtils.toJson(userInfo),EXPIRE_TIME);
                return userInfo.getId();
            }else{
                throw new BlogException("插入用户失败");
            }
        }catch (Exception e){
            log.error("插入用户失败");
            throw new BlogException("插入用户失败");
        }
    }

    private String buildKey(String key){
        if(key==null){
            return null;
        }
        return redisUtils.buildKey(PREFIX,key);
    }

    public void checkUserInfo(UserInfoRegisterRequest userInfoRegisterRequest){
        //校验用户名
        UserInfo userInfo=selectUserInfoByName(userInfoRegisterRequest.getUserName());
        if(userInfo!=null){
            throw new BlogException("用户名重复");
        }
        if(!RegexUtil.checkURL(userInfoRegisterRequest.getGiteeUrl())){
            throw new BlogException("Gitee地址不合法");
        }
        if(!RegexUtil.checkMail(userInfoRegisterRequest.getEmail())){
            throw new BlogException("邮箱地址不合法");
        }
    }

    public UserInfo selectUserInfoByName(String userName) {
        return userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                .eq(UserInfo::getUserName, userName).eq(UserInfo::getDeleteFlag, 0));
    }
    private UserInfo selectUserInfoById(Integer userId) {
        return userInfoMapper.selectOne(new LambdaQueryWrapper<UserInfo>()
                .eq(UserInfo::getId, userId).eq(UserInfo::getDeleteFlag, 0));
    }
}
